package com.xjl.tools;

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicQueue <T>{

    private  AtomicInteger head;
    long p1,p2,p3,p4,p5,p6,p7;
    //可消费位置标记
//    @Contended
    private  AtomicInteger tail;
    long p8,p9,p10,p11,p12,p13,p14;

    //队列大小,需要为2的幂次方
    private int size = 1<<4;

    //取模的值
    private int mod = size -1;

    //data  环形数组
    private T[] data;

    //可用标记数组  环形数组
    private byte[] valid;



    public AtomicQueue(){
        data = (T[])new Object[size];
        valid = new byte[size];
        head = new AtomicInteger(0);
        tail = new AtomicInteger(0);
    }

    public AtomicQueue(int size){
        if((size<0 || (size&(size-1))!=0)){
            throw new RuntimeException("AtomQueue size must be 2**n!!\n");
        }

        this.size = size;
        this.mod = size -1;;
        this.data = (T[])new Object[size];
        this.valid = new byte[size];
        head = new AtomicInteger(0);
        tail = new AtomicInteger(0);
    }

    public boolean push(T item){
        int tailT = this.tail.get();
        int headT = this.head.get();
        //首先判断队列是否已满
        tailT = tailT<=headT? (tailT+size): (tailT);
        if(tailT<=headT+1){
            return false;
        }

        //表示该位置已经被生产
        if(valid[headT]!=0){
            return false;
        }

        //使用CAS来进行生产,可生产标记+1,之后再生产元素
        if(!this.head.compareAndSet(headT,(headT+1)&mod)){
            return false;
        }

        this.data[headT] = item;
        this.valid[headT] = 1;
        return true;
    }

    public T pop(){
        int headT,tailT;
        headT = this.head.get();
        tailT= this.tail.get();

        //队列为空,或者该位置无元素
        if(headT==tailT||valid[tailT]==0){
            return null;
        }
        //使用CAS进行消费标记+1,之后再标记
        if(!this.tail.compareAndSet(tailT,(tailT+1)&mod)){
            return null;
        }
        this.valid[tailT] = 0;
        return data[tailT];
    }

}
